﻿// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

using Neto.PermissionGenerate;

namespace Neto.Core.Utils.Extensions;

public static class MenuExtensions
{
    /// <summary>
    ///     菜单类型
    /// </summary>
    public enum MenuType
    {
        /// <summary>
        ///     目录
        /// </summary>
        目录 = 0,

        /// <summary>
        ///     菜单
        /// </summary>
        菜单 = 1,

        /// <summary>
        ///     API 接口
        /// </summary>
        API = 2,

        功能方法 = 3,

        /// <summary>
        ///     控制器
        /// </summary>
        控制器 = 4
    }

    /// <summary>
    ///     获取菜单
    /// </summary>
    /// <param name="menus"></param>
    /// <param name="pid">父级ID</param>
    /// <param name="area">区域</param>
    /// <returns></returns>
    public static List<ApiMenuRouteOut> GetMenus(this List<MenuRouteItem> menus, string pid = "", string area = "")
    {
        var menuItems = new List<ApiMenuRouteOut>();
        foreach (var menu in menus.Where(o => o.PCode != null && o.PCode.ToLower() == pid.ToLower())
                     .OrderBy(o => o.Sort))
        {
            if ((menu.PgType == PgType.Directory && menu.IsControllerCatalogue == false) ||
                (menu.PgType == PgType.Controller && menu.IsControllerCatalogue == false)) //目录
            {
                //MVC 目录，
                var menuitem = new ApiMenuRouteOut
                {
                    Name = menu.Name,
                    Path = menu.Url,
                    PgType = menu.PgType,
                    Component = "layout.base",
                    Meta = new ApiMenuMeta
                    {
                        Title = menu.Title,
                        I18nKey = menu.I18nKey,
                        Icon = menu.Icon,
                        Order = menu.Sort
                    }
                };
                if (!string.IsNullOrWhiteSpace(menu.Url)) menuitem.Path = $"/{menu.Url.TrimStart('/')}";

                menuitem.Children = GetMenus(menus, menu.Code, area);
                menuItems.Add(menuitem);
            }
            else if ((menu.PgType == PgType.Directory && menu.IsControllerCatalogue) ||
                     (menu.PgType == PgType.Controller && menu.IsControllerCatalogue)) //目录
                //处理MVC 有Controller 目录的情况，防止生成多余的空菜单目录
                foreach (var menuitem in menus.Where(o =>
                                 o.PCode != null && o.PCode.ToLower() == menu.Name.ToLower() && o.PgType == PgType.Menu)
                             .OrderBy(o => o.Sort))
                    AddMenu(menuitem);
            else if (menu.PgType == PgType.Menu)
                //菜单
                AddMenu(menu);

            void AddMenu(MenuRouteItem menu)
            {
                var menuitem = new ApiMenuRouteOut
                {
                    Name = menu.Name,
                    PgType = menu.PgType,
                    //Component = $"view.{menu.Name}",
                    Meta = new ApiMenuMeta
                    {
                        Title = menu.Title,
                        I18nKey = menu.I18nKey,
                        Icon = menu.Icon,
                        Order = menu.Sort,
                        HideInMenu = menu.IsHideMenu
                    }
                };


                if (!string.IsNullOrWhiteSpace(menu.Url))
                {
                    menuitem.Path = $"/{menu.Url.TrimStart('/')}";


                    if (menuitem.Path.Contains(":"))
                    {
                        menuitem.HasProps = true;

                    }
                }


                //判断有没有参数

                //if (menu.IsProps == true)
                //{
                //    menuitem.HasProps = true;
                //}
                switch (menu.OpenType)
                {
                    case MenuOpenType.默认:
                        menuitem.Component = $"view.{menu.Name}";
                        break;
                    case MenuOpenType.内链:
                        menuitem.Component = "view.iframe-page";
                        menuitem.Props = new ApiMenuProp { Url = menu.Href };
                        break;
                    case MenuOpenType.外链:
                        menuitem.Component = "view.iframe-page";
                        menuitem.Meta.Href = menu.Href;
                        break;
                }


                //如果是这样,意味着他是第一级的菜单,这种情况下需要特殊设置
                if (pid == area) menuitem.Component = $"layout.base${menuitem.Component}";
                menuItems.Add(menuitem);
            }

            //}
        }


        //排序
        return [.. menuItems.OrderBy(it => it.Meta?.Order)];
    }

    public class MenuRouteItem
    {
        /// <summary>
        ///     节点类型(菜单、工具栏)
        /// </summary>
        public PgType PgType { get; set; }

        /// <summary>
        ///     本节点Id
        /// </summary>
        public string Code { get; set; }

        /// <summary>
        ///     父节点Id
        /// </summary>
        public string PCode { get; set; }


        /// <summary>
        ///     菜单ID，全局唯一标识
        /// </summary>
        public string Name { get; set; }


        /// <summary>
        ///     菜单名称
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        ///     多语言key
        /// </summary>
        public string I18nKey { get; set; }

        /// <summary>
        ///     图标
        /// </summary>
        public string Icon { get; set; }

        /// <summary>
        ///     顺序(按从小到大排序)
        /// </summary>
        public int Sort { get; set; }

        /// <summary>
        ///     Url
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        ///     内外链路径
        /// </summary>
        public string Href { get; set; }

        /// <summary>
        ///     打开方式
        /// </summary>
        public MenuOpenType OpenType { get; set; }

        /// <summary>
        ///     是否控制器目录
        ///     注意：控制器目录不生成为后台菜单层次机构中去，不然多出来一层，要把这个换成菜单
        ///     sysmenu表里已经没有这个字段了
        /// </summary>
        [Obsolete]
        public bool IsControllerCatalogue { get; set; }

        /// <summary>
        ///     控制器Code,自动生成获取
        /// </summary>
        public string ControllerCode { get; set; }
        public bool IsHideMenu { get; set; }

        [Obsolete]
        public bool IsProps { get; set; }
    }


    public class ApiMenuRouteOut
    {
        /// <summary>
        ///     名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        ///     路径
        /// </summary>
        public string Path { get; set; }

        public string Component { get; set; }

        public ApiMenuProp Props { get; set; }

        /// <summary>
        /// 是否存在参数
        /// </summary>
        public bool HasProps { get; set; }


        public ApiMenuMeta Meta { get; set; }

        /// <summary>
        ///     子页面
        /// </summary>
        public List<ApiMenuRouteOut> Children { get; set; }

        /// <summary>
        ///     菜单类别
        /// </summary>
        public PgType PgType { get; set; }
    }

    public class ApiMenuProp
    {
        /// <summary>
        ///     内链地址
        /// </summary>
        public string Url { get; set; }
    }

    public class ApiMenuMeta
    {
        public string Title { get; set; }
        public string I18nKey { get; set; }

        /// <summary>
        ///     图标
        /// </summary>
        public string Icon { get; set; }

        /// <summary>
        ///     排序
        /// </summary>
        public int Order { get; set; }

        public bool Constant { get; set; }
        public bool HideInMenu { get; set; }

        /// <summary>
        ///     外链地址
        /// </summary>
        public string Href { get; set; }
    }
}